const util = require('./util')

//搜索设备
const searchDevs = async (call) =>{

  try{

    //打开蓝牙适配器
    await wx.openBluetoothAdapter()

    //启动蓝牙设备搜索
    await wx.startBluetoothDevicesDiscovery({
      allowDuplicatesKey:true,
      services: ['0000ffe0-0000-1000-8000-00805f9b34fb']
    })

    /** 检测查询到的设备
    返回的单个对象数据结构
    RSSI: -66
    advertisServiceUUIDs: ["0000FFE0-0000-1000-8000-00805F9B34FB"]
    deviceId: "0AD88C19-83CB-E5BE-39AC-C7601F6A5C0A"
    localName: "HX-BLE"
    name: "HX-BLE"
    */
    wx.onBluetoothDeviceFound(data => call(data.devices))

  }catch(e){
    util.catchError(e)
  }

}

//寻找设备 一旦发现设备立即返回设备列表 超时返回空数组
const searchDevsImmediately =  (timeout=5) => {
  let findState=false;
  const resolveData = resolve => devs => {
    if(!findState){
      findState=true;
      resolve(devs)
      closeSearchDevs()
    }
  }
  return new Promise( async (resolve,reject) => {
    const refn = resolveData(resolve)
    await searchDevs(refn)
    setTimeout(()=>refn([]),timeout*1000)
  })
}


//关闭蓝牙搜索
const closeSearchDevs = async ()=>{
  await wx.stopBluetoothDevicesDiscovery()
}

//连接蓝牙设备  返回连接的设备信息
const connectDevs = async targetDev  => {
  const {deviceId} = targetDev;
  
  await wx.createBLEConnection({deviceId})
  const {services} = await wx.getBLEDeviceServices({deviceId})
  const {platform} = await wx.getSystemInfo()

  let serviceId = "";
  if(platform == 'ios'){
    serviceId = services[services.length - 1].uuid; 
  }else{
    serviceId = services[services.length - 3].uuid; 
  }

  const {characteristics} = await	wx.getBLEDeviceCharacteristics({deviceId,serviceId})
  const characteristicId = characteristics[0].uuid;

  const specialData =  {deviceId,serviceId,characteristicId};

  await wx.notifyBLECharacteristicValueChanged({
    ...specialData,state:true
  })

  return {...targetDev,...specialData,isConnect:true};
}

//自动连接
const auteConnect = async ()=>{
  wx.showLoading({
    title: '正在连接',
  })
  const findDevs = await searchDevsImmediately()
  if(findDevs.length == 0){
    wx.showToast({
      icon:'error',
      title: '未发现',
    })
    throw 'not find the devices'
  }
  wx.hideLoading()
  return await connectDevs(findDevs[0])
}

/**
 * 向设备写入指令 默认返回一条结束
 * device 设备
 * value 写入的值
 * condition:Function 条件判断函数 (count:Integer 循环次数，index:Integer 数据长度)
 * 
 */
const writeInstruct =  async (device,writeData,condition) => {
  condition = condition || function(count){ return count ==0 };
  return new Promise(async (resolve,reject) => {
    let cardInfoArray = new Array();
    let index = 0;
    let count=0;
    wx.onBLECharacteristicValueChange(( {value} ) => {
      let intArray = new Uint8Array(value)

      if(condition(count,index)){
        resolve(intArray)
        return;
      }

      for (var i = 0; i < intArray.byteLength; i++) {
        cardInfoArray[index] = intArray[i]
        index++ //二代证 1297 三代证2321
      }

      if(condition(count,index)){
        resolve(cardInfoArray)
        return;
      }
      
      count++;
    })

    await wx.writeBLECharacteristicValue({
      ...device,
      value: util.stringToArrayBuffer(writeData)
    })
  })
}

/**
 * 读取身份证
 * device 设备
 * useLoading 是否启用加载遮罩
 */
const readIdCard = async (device,useLoading=false) => {

   if(useLoading)
      wx.showLoading({
        title: '读取中',
      })

    //1.写入寻卡指令
   const searchBuffer = await writeInstruct(device,'aaaaaa96690003200122')
   if(!util.searchCardIsOk(searchBuffer)){
     util.error('寻卡失败')
   }

    //2.写入选卡指定
    const selectBuffer = await writeInstruct(device,'aaaaaa96690003200221')
    if(!util.selectCardIsOk(selectBuffer)){
      util.error('选卡失败')
    }
   
    //3.写入读卡指令
    //身份证读取结束条件
    const idCardEndCondition = (count,index) =>  index == 2321 || index == 1295;
    const idCardArray = await writeInstruct(device,'aaaaaa96690003300132',idCardEndCondition)

    //4.解析身份证
    const result = util.readCardIsOk(idCardArray)

    useLoading && wx.hideLoading({})

    return result;
}

//内置 已经连接的设备
let _connectDev = null;

//监听已经连接的设备
const _listenConnectDevState = ()=>{
  //一旦蓝牙设备改变 就重置连接设备 
  wx.onBluetoothAdapterStateChange(function (res) {
    if(!res.available)
      _connectDev = null;
  })

}

//自动连接搜索读取
const autoReadIdCard = async ()=>{
    if(!_connectDev){
      wx.showLoading({
        title: '查询设备',
      })
      const findDevs = await searchDevsImmediately()
      if(findDevs.length == 0){
        wx.showToast({
          title: '无设备',
          icon:'error'
        })
        throw 'not find the devs'
      }
      wx.showLoading({
        title: '连接中',
      })
      _connectDev = await connectDevs(findDevs[0])
      wx.hideLoading({})
    }
    wx.showLoading({
      title: '读取中',
    })
    const idCard = await readIdCard(_connectDev)
    wx.hideLoading({})
    _listenConnectDevState();//监听状态
    return idCard;
}



module.exports = {
  searchDevs,
  searchDevsImmediately,
  closeSearchDevs,
  connectDevs,
  readIdCard,
  auteConnect,
  autoReadIdCard
}